//
//@File    :	15.12_error5.cpp
//@Time    :	2022/03/10 14:44:24
//@Auther  :	Sun Sheng
//@Contact :	970340843@qq.com
//@Desc    :	unwinding the stack
//

#include <iostream>
#include <cmath>
#include <string>
#include "15.10_exc_mean.h"

class demo
{
private:
    std::string word;
public:
    demo(const std::string &str) {
        word = str;
        std::cout<<"demo "<<word<<" created\n";
    }
    ~demo() {
        std::cout<<"demo "<<word<<" destroyed\n";
    }
    void show() const{
        std::cout<<"demo "<<word<< "lives!\n";
    }
};

double hmean(double a,double b);
double gmean(double a,double b);
double means(double a,double b);

int main()
{
    using std::cout;
    using std::cin;
    using std::endl;

    double x,y,z;
    {
        demo d1("found in block in main()");
        cout<<"Enter two numbers: ";
        while (std::cin>>x>>y)
        {
            try{ //start of try block
                z=means(x,y);
                cout<<"The mean mean of "<<x
                    <<" and "<<y<<"is"<<z<<endl;
                cout<<"Enter next pair";
            }//end of try block
            catch(bad_hmean & bg)//start of catch block
            {
                bg.mesg();
                cout<<"Try again.\n";
                continue;//产生异常时跳过循环
            }
            catch(bad_gmean & hg)
            {
                cout<<hg.mesg();
                cout<<"Values used: "<<hg.v1<<", "<<hg.v2<<endl;
                cout<<"Sorry,you don't get to paly any more.\n";
                break;//产生异常时结束循环
            }//end of catch block
        }
        d1.show();
    }
    cout<<"Bye!\n";
    //用来暂停
    cin.get();
    cin.get();
    return 0;
}

double hmean(double a,double b){
    if (a==-b)
    {
       throw bad_hmean(a,b);
    }//调用构造函数bad_hmean(),以初始化对象,使其存储参数值
    return 2.0*a*b/(a+b);
}

double hmean(double a,double b){
    if (a<0||b<0)
    {
       throw bad_gmean(a,b);
    }
    return std::sqrt(a*b);
}

double means(double a,double b){
    double am,hm,gm;
    demo d2("found in means()");
    am=(a+b)/2.0;
    try
    {
        hm=hmean(a,b);
        gm=gmean(a,b);
    }
    catch(bad_hmean & bg)
    {
        bg.mesg();
        std::cout<<"Cought in means()\n";
        throw;//rethore the exception
    }
    d2.show();
    return (am+hm+gm)/3.0;
}